package bma.common.thrift;

import org.apache.thrift.TApplicationException;
import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TMessageType;
import org.apache.thrift.protocol.TProtocol;

public abstract class TProcessor4Error implements TProcessor {

	final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(TProcessor4Error.class);

	public TProtocolCacheMessage wrapIn(TProtocol in) {
		return TProtocolCacheMessage.wrapIn(in);
	}

	protected boolean process(TProcessor p, TProtocol in, TProtocol out)
			throws TException {
		TMessage msg = null;
		in = wrapIn(in);
		msg = in.readMessageBegin();
		try {
			return p.process(in, out);
		} catch (TApplicationException e) {
			writeException(e, msg, out);
			return false;
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("process (" + msg.name + ") fail", e);
			}
			handleException(e, msg, out);
			return false;
		}
	}

	protected void handleException(Throwable e, TMessage msg, TProtocol out) {
		TApplicationException x = new TApplicationException(
				TApplicationException.INTERNAL_ERROR, e.getMessage());
		writeException(x, msg, out);
	}

	protected void writeException(TApplicationException x, TMessage req,
			TProtocol out) {
		try {
			out.writeMessageBegin(new TMessage(req.name,
					TMessageType.EXCEPTION, req.seqid));
			x.write(out);
			out.writeMessageEnd();
			out.getTransport().flush();
		} catch (Exception e) {
			if (log.isDebugEnabled()) {
				log.debug("writeException fail", e);
			}
		}
	}
}
